/*
 * rules.c
 *
 *  Created on: 2012/09/24
 *      Author: owner
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rule_info.h"

#define RULE_NAME_SIZE	8
typedef struct _SELRULE {
	CHAR ruleID[RULE_NAME_SIZE];
	struct _SELRULE * next;
} SELRULE, *PSELRULE;
PSELRULE stSelRule = NULL;

PRULEMAN DLL_EXPORT stRuleManager = NULL;

extern void regAllRules();

static VOID turnOnRules(VOID) {
	PSELRULE cur1 = stSelRule;
	PRULEMAN cur2 = NULL;
	BOOL flag = FALSE;
	while (cur1 != NULL ) {
		cur2 = stRuleManager;
		flag = FALSE;
		while (cur2 != NULL ) {
			if (!strcmp(cur1->ruleID, cur2->ruleID)) {
				cur2->ruleSwitch = ON;
				flag = TRUE;
			}
			cur2 = cur2->nextRule;
		}
		if (!flag) {
			printf("WARING: RULE[%s] not existed!\n", cur1->ruleID);
		}
		cur1 = cur1->next;
	}
}

VOID DLL_EXPORT AddSelRule(PSZ rule) {
	PSELRULE * curRule = NULL;
	PSELRULE newRule = NULL;

	if (stSelRule == NULL ) {
		stSelRule = (PSELRULE) malloc(sizeof(SELRULE));
		strcpy(stSelRule->ruleID, rule);
		stSelRule->next = NULL;
	} else {
		newRule = (PSELRULE) malloc(sizeof(SELRULE));
		strcpy(newRule->ruleID, rule);
		newRule->next = NULL;
		curRule = &stSelRule;
		while ((*curRule)->next != NULL ) {
			curRule = &((*curRule)->next);
		}
		(*curRule)->next = newRule;
	}
}

INT DLL_EXPORT RuleInitial(VOID) {
	regAllRules();
	turnOnRules();
	return EXIT_SUCCESS;
}

S4 DLL_EXPORT RuleMain_cmd(AST index, U4 event) {
	PRULEMAN curRule = stRuleManager;
	while (curRule != NULL ) {
		if (curRule->ruleSwitch && curRule->ruleMain_cmd != NULL ) {
			printf("RUNNING %s...\n",curRule->ruleID);
			curRule->ruleMain_cmd(index, event);
			printf("%s END.\n",curRule->ruleID);
		}
		curRule = curRule->nextRule;
	}
	return EXIT_SUCCESS;
}

S4 DLL_EXPORT RuleMain_ast(U2 kind, AST index, U4 event) {
	PRULEMAN curRule = stRuleManager;
	while (curRule != NULL ) {
		if (curRule->ruleSwitch && curRule->ruleMain_ast != NULL ) {
			printf("RUNNING %s...\n",curRule->ruleID);
			curRule->ruleMain_ast(kind, index, event);
			printf("%s END.\n",curRule->ruleID);
		}
		curRule = curRule->nextRule;
	}
	return EXIT_SUCCESS;
}

S4 DLL_EXPORT RuleMain_cpp(AST index, AST tuIdx) {
	PRULEMAN curRule = stRuleManager;
	while (curRule != NULL ) {
		if (curRule->ruleSwitch && curRule->ruleMain_cpp != NULL ) {
			printf("RUNNING %s...\n",curRule->ruleID);
			curRule->ruleMain_cpp(index, tuIdx);
			printf("%s END.\n",curRule->ruleID);
		}
		curRule = curRule->nextRule;
	}
	return EXIT_SUCCESS;
}

INT DLL_EXPORT RuleClose(VOID) {
	PSELRULE cur = stSelRule;
	PSELRULE tmp = NULL;

	PRULEMAN tmpRule = NULL;
	PRULEMAN curRule = stRuleManager;
	PRULEOUT tmpNode = NULL;
	PRULEOUT traceNode = NULL;

	while (cur != NULL ) {
		tmp = cur->next;
		free(cur);
		cur = tmp;
	}
	stSelRule = NULL;

	while (curRule != NULL ) {
		traceNode = *(curRule->headOut);
		while (traceNode != NULL ) {
			tmpNode = traceNode->next;
			free(traceNode);
			traceNode = tmpNode;
		}
		*(curRule->headOut) = NULL;
		*(curRule->tailOut) = NULL;
		curRule->headOut = NULL;
		curRule->tailOut = NULL;
		free(curRule);
		curRule = tmpRule;
	}
	stRuleManager = NULL;
	return EXIT_SUCCESS;
}
